//
//  NavBarViewController.m
//  NavBar
//
//  Created by Thiago on 23/07/2009.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "NavBarViewController.h"
#import "NavBarAppDelegate.h"
#import "ActionPickerViewController.h"
#import "ModalViewController.h"
#import "AboutViewController.h"
#import "UserPreferencesViewController.h"
#import <CommonCrypto/CommonDigest.h>
#import "ElementParser.h"

@implementation NavBarViewController

@synthesize actionVC, webView, statsVC, prefVC, aboutVC;


-(void)loginWithUserPrefData:(id)sender{
	
   	
	//Load URL out of preferences
	NavBarAppDelegate *delegate = (NavBarAppDelegate *) [ [ UIApplication sharedApplication] delegate];
	NSString *prefUrlString = [[delegate userPrefences] objectAtIndex:0];
	
	//TODO: Check if any URL there, if not default to lotgd.net
	if([prefUrlString isEqualToString:@""]){
		prefUrlString = [[NSString alloc] initWithString:@"http://www.lotgd.net"];
		NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
		[prefs setValue:[NSString stringWithString:prefUrlString] forKey:@"userBaseURL"];
		[delegate loadPreferences];
	}
	
	//Check if preference URL includes http:// prefix
	if(![[prefUrlString substringToIndex:7] isEqualToString:@"http://"]){
		
		prefUrlString = [@"http://" stringByAppendingString:prefUrlString];
		//Save to preferences
		NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
		[prefs setValue:[NSString stringWithString:prefUrlString] forKey:@"userBaseURL"];
	}
	
	NSURL *loginURL = [NSURL URLWithString:[prefUrlString stringByAppendingString:@"/login.php"]];
	
	NSString  *username = [NSString alloc];
	NSString  *password = [NSString alloc];
	
	if([[delegate userPrefences] count] > 1)
	{	
		username = [username initWithString: [[delegate userPrefences] objectAtIndex:1]];
		password = [password initWithString: [[delegate userPrefences] objectAtIndex:2]];
	}
	else
	{
		username = [username initWithString:@""];
		password = [password initWithString:@""];
		loginURL = [NSURL URLWithString:prefUrlString];
	}	
	// NSLog(@"Got preferred URL:  %@, username: %@",  loginURL, username);

	
	//MD5 password generation
	NSString *md5password = [[NSString alloc] initWithString:@"!md5!"];
	md5password = [md5password stringByAppendingString:[self md5:password]];
	
	//Needs to lower case as the server PHP compares against it and our MD5 function returns upper case
	md5password = [md5password lowercaseString];
	NSDictionary *loginDict = [[NSDictionary alloc] initWithObjectsAndKeys:
							   username, @"name",
							   md5password, @"password",
							   nil];
	
	//Prepare POST message
	NSString *bounds = @"AaB03x";
	
	NSData *formData = [self createFormData:loginDict withBoundary:bounds];
	NSString *formStr = [[NSString alloc] initWithData:formData encoding:NSASCIIStringEncoding];
	// NSLog(@"HTTP POST form data: ,%@", formStr);
	
	NSMutableURLRequest *loginRequest = [NSMutableURLRequest requestWithURL: loginURL];
    NSString *content = [NSString stringWithFormat:@"multipart/form-data;boundary=%@",bounds];
	[loginRequest setValue:content forHTTPHeaderField:@"Content-type"];
    [loginRequest setHTTPMethod:@"POST"];
	[loginRequest setHTTPBody:formData];
	
	//POST login request
	[self processRequest:loginRequest];
}

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
	
	//Initialize view
	NavBarAppDelegate *delegate = (NavBarAppDelegate *) [ [ UIApplication sharedApplication] delegate];
	webView = [delegate myWebView];

    [self loginWithUserPrefData:self];
	
	//Initialization of UI crap
	// Create nav bar buttons for Action and Stats
	
	NSMutableArray *barItems = [[NSMutableArray alloc] init];
	
	UIBarButtonItem *actionButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Action" style:UIBarButtonItemStyleBordered
																		target:self action:@selector(actionPickerViewAction:)];
	[barItems addObject:actionButtonItem];

	UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
	[barItems addObject:flexSpace];		
		
	UIBarButtonItem *statsButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Stats" style:UIBarButtonItemStyleBordered
																	   target:self action:@selector(modalViewAction:)];
	[barItems addObject:statsButtonItem];
	/*
	UIBarButtonItem *testButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Preferences" style:UIBarButtonItemStyleBordered
																	   target:self action:@selector(preferencesViewAction:)];
	[barItems addObject:testButtonItem];*/
	
	UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
	infoButton.alpha = 0.5;
	infoButton.frame = CGRectMake( 290, 0, 30, 30);	
	
	[infoButton addTarget:self action:@selector(aboutViewAction:) forControlEvents:UIControlEventTouchUpInside];
	
	UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0,410,320,50)];
	[toolBar setItems:barItems];

	[actionButtonItem release];
	[statsButtonItem release];
	// [testButtonItem release];
	self.view = webView;
	[self.view addSubview:toolBar];
	[self.view addSubview:infoButton];

}

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}

//#pragma mark -
//#pragma mark API

- (IBAction)modalViewAction:(id)sender
{
    if (self.statsVC == nil)
        self.statsVC = [[[ModalViewController alloc] init] autorelease];
	
	UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:statsVC];
	
	[self.navigationController presentModalViewController:nav animated:YES];
	
	self.statsVC = nil;
	[statsVC release];
}

- (IBAction)aboutViewAction:(id)sender
{
    if (self.aboutVC == nil)
        self.aboutVC = [[[AboutViewController alloc] init] autorelease];
	
	UINavigationController *about = [[UINavigationController alloc] initWithRootViewController:aboutVC];
	
	[self.navigationController presentModalViewController:about animated:YES];
	
	[aboutVC release];
}

-(IBAction)preferencesViewAction:(id)sender {
    if (self.prefVC == nil)
        self.prefVC = [[[UserPreferencesViewController alloc] init] autorelease];
	
	UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:prefVC];
	
	[self.navigationController presentModalViewController:nav animated:YES];
	
	[prefVC release];
}	

-(void)actionPickerViewAction:(id)sender {
	NavBarAppDelegate *delegate = (NavBarAppDelegate *) [ [ UIApplication sharedApplication] delegate];
	int isAVLoaded = delegate.isAVLoaded;

  	if ( isAVLoaded == 0 ) {
		self.actionVC = [[ActionPickerViewController alloc] init];	
		UIView * testView = [self.actionVC returnView];
		self.view = testView;
		
		delegate.isAVLoaded = 1;
	} else {
	 	[self.actionVC dropView];
	}	
}

//Relative URL load requests generated and called from the code
-(void)processURL:(NSURL*)relativeurl{

	// Send away request
	// NSLog(@"Processing URL: %@", (NSString*)relativeurl);
	NSMutableString * webstring = [[NSMutableString alloc] initWithContentsOfURL: relativeurl ];
	
	//Delegate result processing
	[self parseResult:webstring];
}	

//Requests coming from a user interacting with WebView 
-(void)processRequest:(NSURLRequest*)request{

	//Send request
	NSURLResponse *response;
	NSError *error;
	NSData *myReturn = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
	
	//Delegate result processing
	NSString *returnStr = [[NSString alloc] initWithData:myReturn encoding:NSASCIIStringEncoding];
	if ( [returnStr isEqualToString:@""] ) {
		// Did not get anything back from login attempt, assume no internet
		[self thereIsNoInternet];		
	}	
	else {
		// Parser returned page just fine
		[self parseResult:returnStr ];		
	}	
}

-(void)thereIsNoInternet {
	// Add a view on top of the webview to warn people about their lack of connection
	UIView *prefView = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)];
	prefView.backgroundColor = [UIColor redColor];
	[webView addSubview:prefView];
	
	UILabel *URLLabel =
	[[[UILabel alloc]
	  initWithFrame:
	  CGRectMake(10,10,300,20)]
	 autorelease];
	URLLabel.font = [UIFont boldSystemFontOfSize:17];
	URLLabel.text = [[NSString alloc] initWithString:@"Best we can tell, you are not online"];
	
	[prefView addSubview:URLLabel];
}	


-(void)parseResult:(NSString*)webstring{

	
	//NSMutableURLRequest *request = [NSMutableURLRequest alloc];
	
	//Set up parser and look for center frame
	ElementParser* parser = [[[ElementParser alloc] init] autorelease];
	DocumentRoot* root = [parser parseHTML: webstring];
	
	//Retrieve head source for CSS and JS hijinx
	NSString* headSource = [[NSString alloc] initWithString:[[root selectElement: @"head"] contentsSource]];
	// if (headSource != @"") // NSLog(@"headSource found!");
	
	//Retrieve body tag for the background and font color
	NSString* bodyTag = [[NSString alloc] initWithString:(NSString*)[[root selectElement:@"body"] description]];
	// NSLog(@"bodyTag found: ,%@", bodyTag);
	
	//Retrieve the center frame we want to display
	

	NSArray* middleFrames = [root selectElements:@"td.headrow table"];
	// NSLog(@"Possible center frames found: %d", [middleFrames count]);
	
	//If none found, we are probably on the FAQ pages
	if([middleFrames count] < 1){
	  	middleFrames = [root selectElements:@"td.headrow"];
	}
	
	Element* centerTable = [middleFrames objectAtIndex:0];
	
	NSString *centerFrame = [[NSString alloc] initWithString:[[[centerTable selectElements:@"td"]  objectAtIndex:0] contentsSource]];
	
	//TEC: Due to parser bug in contentsSource with the weapon store inventory table we are 
	// forced to get a higher element (table instead of td), so we check if there is an 
	// abnormally high count of columns in the center frame
	if ([[[centerTable selectElement:@"tr"] childElements] count] > 2) {
		//
		centerFrame = [[NSString alloc] initWithString:[[middleFrames objectAtIndex:0] contentsSource]];
		
	}
	// NSLog(@"Number of tds: %d", [[[centerTable selectElement:@"tr"] childElements] count]);
	//// NSLog(@"Center frame source: %@", centerFrame);
	
	//PARSE ACTIONS
	//Parse for nav bar actions and corresponding URLs
	NSArray* actions = [root selectElements: @"a.nav"];
	
	// NSLog(@"actions found:%d", [actions count]);
	
	//Store action elements in arrays
	NSMutableArray* actionDescrArray = [[NSMutableArray alloc] init];
	NSMutableArray* actionURLArray = [[NSMutableArray alloc] init];

	
	//Load base URL out of preferences
	NavBarAppDelegate *delegate = (NavBarAppDelegate *) [ [ UIApplication sharedApplication] delegate];
	NSString* baseurlStr = [[delegate userPrefences] objectAtIndex:0];
	
	//Check if preference URL includes http:// prefix
	if(![[baseurlStr substringToIndex:7] isEqualToString:@"http://"]){
		
		baseurlStr = [@"http://" stringByAppendingString:baseurlStr];
	}
	
	//And add slash postfix if missing
	if (![[baseurlStr substringFromIndex: [baseurlStr length]-1] isEqualToString:@"/"]){
		
		baseurlStr = [baseurlStr stringByAppendingString:@"/"];
		
	};
	
	NSURL* baseurl = [[NSURL alloc] initWithString:baseurlStr];
	
	//Get actions and links 
	for (Element* action in actions){
		NSString* actionDescr = [[NSString alloc] initWithString: [action contentsText]];
		NSString* actionRelURL = [[NSString alloc] initWithString: [action attribute:@"href"]];
		
		
		//Remove shortcut parentheses
		if([[actionDescr substringToIndex:1] isEqualToString:@"("]){
			actionDescr = [[NSString alloc] initWithString:[actionDescr substringFromIndex:4]];
		}
		
		 
		[actionDescrArray addObject:actionDescr];
		
		// If "http://" in actionRelURL, then it's not relative
		// Override concat with baseURL in that case

		if([[actionRelURL substringToIndex:7] isEqualToString:@"http://"]){
			[actionURLArray addObject:actionRelURL];
		}else{
			[actionURLArray addObject:[baseurlStr stringByAppendingString: actionRelURL]];
		}
	
		[actionDescr release];
		[actionRelURL release];
		
		// // NSLog(@"url for action %@ is: %@", actionDescr, actionRelURL);
	}
	
	//Copy newly parsed action to app delegate

	delegate.actionDescrArray = actionDescrArray;
	delegate.actionURLArray = actionURLArray;
	
	[actionDescrArray release];
	[actionURLArray release];
	
	//PARSE STATS
	
	int i = 1;	
	int h = 0;
	NSArray* items = [root selectElements: @"table.charinfo"];
	// NSLog(@"table.charinfo found %i time(s)", [items count]);
	// NSLog(@"td charhead found %i time(s)", [[root selectElements:@"td.charhead" ] count]);
	
	//Initialize structure elements
	NSMutableArray *sectionArray = [[NSMutableArray alloc] init];
	NSMutableArray *sectionContents = [[NSMutableArray alloc] init];
	
		NSArray *chartrs = [root selectElements: @"table.charinfo tr"];
		
		NSString *currSection = [[NSString alloc] init];
		// NSLog(@"tr's found within table.charinfo: %i", [chartrs count]);
		for (Element* tr in chartrs){
			h++;
			
			//HEADER ROWS
			// NSLog(@"tds found in this tr: %d", [[tr childElements] count]);
				if ( [[tr childElements] count] < 2) {
					
					//We still need to distinguish attr/value rows from Buffs
					Element *tdElement = [[tr childElements ] objectAtIndex:0];
					if([[tdElement attribute:@"class"] isEqualToString:@"charhead"]){
						
						//Only for first header
						if(h == 1){
							currSection = [tdElement contentsText];
						}else{
							// End of section, so add dict data to our sectionArray 
							// and delete sectionContent for new section
							//sectionsContents copy necessary because removeAllObjects will delete everything
							NSDictionary *sectionDict = [[NSDictionary alloc] initWithObjectsAndKeys:
												   currSection, @"GroupName",
												   [sectionContents copy], @"contents",
												   nil];
							[sectionArray addObject:sectionDict];
						
							//Set new section header
							currSection = [tr contentsText];
							[sectionContents removeAllObjects];
						}	
						// NSLog(@"Header: %@ (%i)", [tr contentsText], h);
					}else if([[tdElement attribute:@"class"] isEqualToString:@"charinfo"]){
						
						//Add Buff element
						[sectionContents addObject:[tdElement contentsText]];
						// NSLog(@"-- Buff element: %@ (%i)", [tdElement contentsText], h);
					}
					
					i++;
					
				//ATTRIBUTE/VALUE ROWS
				} else {
					NSArray *tds = [tr childElements];
					
					//Skip row for progress bar table on lotgd.net 
				    if( ![[[tds objectAtIndex:1] contentsText] isEqualToString:@""]){
						//// NSLog(@"-- Attribute: %@ (%i)", [[tds objectAtIndex:0] contentsText], h);
						//// NSLog(@"-- Value: %@ (%i)", [[tds objectAtIndex:1] contentsText], h);
						
						NSMutableString *valueStr = [[NSMutableString alloc] initWithString:[[tds objectAtIndex:1] contentsText]];
						
						//Delete newlines after attribute values used with lotgd.net's progress bar
						while([[valueStr substringFromIndex:[valueStr length]-1] isEqualToString:@"\n"]){
							[valueStr	deleteCharactersInRange:NSMakeRange([valueStr length]-1, 1)];
						}
						NSString *cellString = [[NSString alloc] initWithString: [[tds objectAtIndex:0] contentsText]];
						cellString = [cellString stringByAppendingString:[@"|" stringByAppendingString:valueStr ]];
						
						[sectionContents addObject:[cellString copy]];
						// NSLog(@"--Attribute|Value: %@|", cellString);
						[valueStr release];
						[cellString release];
					}
				}
		}	
	
	//Add last section (usually Buffs)
	NSDictionary *sectionDict = [[NSDictionary alloc] initWithObjectsAndKeys:
								 currSection, @"GroupName",
								 sectionContents, @"contents",
								 nil];
	[sectionArray addObject:sectionDict];
	
	delegate.sectionContents = sectionArray;
	
	//Update web view with center frame
		
	//Wrap some HTML around center Frame
	NSString *centerPage = [[@"<html><head>" stringByAppendingString: headSource] stringByAppendingString:@"</head>"];
		
    centerPage = [centerPage stringByAppendingString:bodyTag];
	centerPage = [[[centerPage stringByAppendingString:@"<table><tr><td><br>"] stringByAppendingString:centerFrame] stringByAppendingString:@"</td></tr></table><p><br><br></p></body></html>"];
	
	[self.webView loadHTMLString: [centerPage copy] baseURL:baseurl];
	[centerPage release];
	
}


// MD5 hash encryption usually done by login page JavaScript,
// so we need to encrypt it ourselves for our automatic login
-(NSString*)md5:(NSString*)str{

	const char *cStr = [str UTF8String];
	unsigned char result[CC_MD5_DIGEST_LENGTH];
	
	CC_MD5( cStr, strlen(cStr), result );
	
	return [NSString 
			stringWithFormat: @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
			result[0], result[1],
			result[2], result[3],
			result[4], result[5],
			result[6], result[7],
			result[8], result[9],
			result[10], result[11],
			result[12], result[13],
			result[14], result[15]
			];
}


//Creates form data necessary for automatic login
-(NSData*)createFormData:(NSDictionary*)dictionary withBoundary:(NSString*)myBounds{
	
	NSMutableData *myReturn = [[NSMutableData alloc] initWithCapacity:5];
	
	NSArray *formKeys = [dictionary allKeys];
	for (int i=0; i < [formKeys count]; i++){
		[myReturn appendData: 
					[[NSString stringWithFormat:@"--%@\n", myBounds] dataUsingEncoding:NSASCIIStringEncoding]
		];
		
		[myReturn appendData:
					[[NSString stringWithFormat:
					  @"Content-Disposition: form-data; name=\"%@\"\n\n%@\n", 
					  [formKeys objectAtIndex:i],
					  [dictionary valueForKey:[formKeys objectAtIndex: i]]]
					 dataUsingEncoding:NSASCIIStringEncoding]
		 ];
	}
	
	[myReturn appendData: [[NSString stringWithFormat:@"--%@--\n", myBounds]
						   dataUsingEncoding: NSASCIIStringEncoding]
	];
	
	return myReturn;
}

	

@end
